class Solution {
public:
    unordered_map<string, string> root;
    unordered_map<string, string> name;
    unordered_map<string, set<string>> pre_res;
    vector<vector<string>> accountsMerge(vector<vector<string>>& accounts) {
        for(auto n : accounts)
        {
            name[n[1]] = n[0];
            if(root.find(n[1]) == root.end()) root[n[1]] = n[1];
            for(int i = 2; i < n.size(); i++)
            {
                if(root.find(n[i]) != root.end())
                {
                    root[find(n[1])] = find(n[i]);
                }
                else
                {
                    root[n[i]] = find(n[1]);
                }
            }
        }
        for(auto n : root)
        {
            pre_res[find(n.first)].insert(n.first);
        }
        vector<vector<string>> result;
        for(auto n : pre_res)
        {
            vector<string> temp({name[n.first]});
            for(auto m : n.second)
                temp.push_back(m);
            result.push_back(temp);
        }
        return result;
    }
    string find(string s) {
        // vector<string> mem;
        while(root[s] != s)
        {
            // mem.push_back(s);
            root[s] = root[root[s]];
            s = root[s];
        }
        // for(string n : mem)
        //     root[n] = s;
        return s;
    }
};
